#include "TcpServer.h"

void TcpServer::setport(int port)
{
    if( port > 5000 && port < 65535 )
    {
        i_port = port;
    }else{
        std::cout << "set port failed!" << std::endl;
    }
}

TcpServer::~TcpServer()
{
    stop_server();
}

bool TcpServer::run_server()
{
    if( b_run)
    {
        std::cout << "server running" << std::endl;
        return false;
    }

    b_run = true;
    if(i_port == 0)
    {
        std::cout << "port error" << std::endl;
        return false;
    }
    i_serversocket = socket(AF_INET,SOCK_STREAM, 0);
    
    int val=1;
    setsockopt(i_serversocket, SOL_SOCKET, SO_REUSEADDR,(char *)val, sizeof(val));
    struct sockaddr_in server_addr;
    //Family TCP
    server_addr.sin_family = AF_INET;
    //port num
    server_addr.sin_port = htons(i_port);
    //ip address
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //bind
    if( -1 == bind(i_serversocket,(struct sockaddr *)&server_addr,sizeof(sockaddr_in)))
    {
        perror("bind");
        return false;
    }

    //listen
    if( -1 == listen(i_serversocket,20) )
    {
        perror("listen");
        return false;
    }

    //客户端套接字
    struct ST_Client st_clientaddr;
    socklen_t length = sizeof(st_clientaddr.addr);

    //新连接并创建子线程
    while(b_run){
        std::cout << "accepting...." << std::endl;
        int i_clientsocket = accept(i_serversocket, (struct sockaddr*)&(st_clientaddr.addr), &length);
        if(i_clientsocket<0)
        {
            perror("connect");
            continue;
        }
        std::cout << i_clientsocket << " 客户连接!" << std::endl;

        st_clientaddr.soc = i_clientsocket;
        vec_clientsocket.push_back(st_clientaddr);
        //put thread pool handle
        boost::asio::post(tp_pool,[=](){
            handle_msg(i_clientsocket);
        });
    }

    return true;
}

void TcpServer::stop_server()
{
    b_run = false;
    for(int i = 0; i < vec_clientsocket.size() ; i++)
    {
        close(vec_clientsocket[i].soc);
    }
    close(i_serversocket);
}

void TcpServer::handle_msg(int client_conn)
{
    //TODO
    char c_msg[MAXSIZE];
    while(b_run)
    {
        memset(c_msg,0,sizeof(c_msg));
        int len = recv(client_conn,c_msg,MAXSIZE,0);
        //cout << "handle_msg: " << c_msg  << " len:" << len << endl;
        if( strcmp(c_msg,"exit")==0 || len <= 0)
        {
            std::cout << client_conn << " 连接断开" << std::endl;
            break;
        }
        std::cout << client_conn << ":" << c_msg << std::endl;
        std::string str_msg(c_msg);
        //处理消息 register login(cookie or user pwd)  smsg  group_msg:
        GL::serverHandle(client_conn,str_msg);
    }

    cout << "clear login socket" <<endl;
    for( std::map<std::string,int>::iterator iter = m_usersocket.begin(); iter != m_usersocket.end(); )
    {
        cout << "second :" << iter->first << endl;
        if( iter->second == client_conn)
        {
            m_usersocket.erase( iter++);
            //
            for (std::map<std::string, std::set<std::string>>::iterator it = m_group.begin(); it != m_group.end(); ++it) {  
                it->second.erase(iter->first); 
            } 
        }else
        {
            ++iter;
        }
    }


    cout << "close login socket" <<endl;
    close(client_conn);
   // pthread_exit(0);


}